﻿using System;
using System.Collections.ObjectModel;
using G.Model;
using G.Runtime;

namespace G.Runtime
{
    public class GameValues : 
        KeyedCollection<string, GameValue>
    {
        public delegate void GameValuesChangedHandler(GameValues pGameValues);
        public event GameValuesChangedHandler ChangedEvent;

        protected GameValueDefs _GameValueDefs;

        internal GameValues()
        { }

        internal GameValues(GameValueDefs pGameValueDefs)
        {
            _GameValueDefs = pGameValueDefs;
            foreach (GameValueDef def in pGameValueDefs)
            {
                Add(def);
            }
        }

        public GameValue Add(GameValueDef def)
        {
            GameValue result = null;
            switch (def.TypeCode)
            {
                case System.TypeCode.Int32:
                    {
                        IntGameValue i = new IntGameValue(def);
                        int value = 0;
                        Int32.TryParse(def.Value, out value);
                        i.Value = value;
                        result = i;
                        base.Add(result);
                        FireChangedEvent();
                    }
                    break;
                case System.TypeCode.String:
                    {
                        StringGameValue s = new StringGameValue(def);
                        s.Value = def.Value;
                        result = s;
                        base.Add(result);
                        FireChangedEvent();
                    }
                    break;
                case System.TypeCode.Boolean:
                    {
                        BooleanGameValue b = new BooleanGameValue(def);
                        bool value = false;
                        Boolean.TryParse(def.Value, out value);
                        b.Value = value;
                        result = b;
                        base.Add(result);
                        FireChangedEvent();
                    }
                    break;
                default:
                    break;
            }

            return result;
        }

        public void Add(GameValues pValues)
        {
            foreach (GameValue v in pValues)
            {
                if (!Contains(v.Def.Name))
                {
                    Add((GameValue)v.Clone());
                }
                else
                {
                    GameValue source = pValues[v.Def.Name];
                    GameValue dest = this[v.Def.Name];

                    switch (source.Def.TypeCode)
                    {
                        case System.TypeCode.Int32:
                            {
                                IntGameValue s = (IntGameValue)(source);
                                IntGameValue d = (IntGameValue)(dest);
                                d.Value += s.Value;
                            }
                            break;
                        case System.TypeCode.Boolean:
                            {
                                BooleanGameValue s = (BooleanGameValue)(source);
                                BooleanGameValue d = (BooleanGameValue)(dest);
                                d.Value = s.Value;
                            }
                            break;
                        default:
                            break;
                    }
                }

                //v.Refresh();
            }

        }

        protected override string GetKeyForItem(GameValue item)
        {
            return item.Def.Name;
        }

        protected override void InsertItem(int index, GameValue item)
        {
            base.InsertItem(index, item);
            FireChangedEvent();
        }

        internal void FireChangedEvent()
        {
            if (ChangedEvent != null)
            {
                ChangedEvent(this);
            }
        }
        
        public override string ToString()
        {
            string s = "";
            foreach(GameValue v in this) 
            {
                s += v.ToString();
            }
            return s;
        }


    }
}
